package com.example.java;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.nio.charset.Charset;

/**
 * 还是用guava提供的布隆过滤器进行测试，这种过滤器无法支持分布式，分布式环境下需要使用redis的布隆过滤器
 * 布隆过滤器（Bloom Filter）是一个叫做 Bloom 的老哥于 1970 年提出的。我们可以把它看作由二进制向量（或者说位数组）和一系列随机映射函数（哈希函数）两部分组成的数据结构。
 * 相比于我们平时常用的的 List、Map 、Set 等数据结构，它占用空间更少并且效率更高，但是缺点是其返回的结果是概率性的，而不是非常准确的。
 * 理论情况下添加到集合中的元素越多，误报的可能性就越大。并且，存放在布隆过滤器的数据不容易删除
 * 布隆过滤器说某个元素存在，小概率会误判。布隆过滤器说某个元素不在，那么这个元素一定不在。
 *
 * 常用于解决缓存穿透的问题。
 * 接口请求时，如果在缓存种没有该id相关数据，会去通过sql查询数据库，这样，如果请求参数为-10，-100这样的负数，
 * redis中肯定不会存在这样的数据，当这样大量的请求过来之后，就会导致sq大量请求l查询问题，则就会绕过redis对数据库造成很大压力甚至崩溃。这样的现象称为redis缓存穿透。
 * 将所有的数据都放入布隆过滤器，布隆过滤器判断数据不存在，这个数据一定是不存在的，就可以直接将请求返回，不需要再去数据库查询是否存在。
 *
 * @author xiaohongfei
 * @createTime 8/29/2022 2:10 PM
 **/
public class BloomFilterTest {


    public static void main(String[] args) {
        guavaBloomFilter();

    }

    /**
     * 方法说明：guava的布隆过滤器
     * @param
     * @return void
     * @throws
     * @Author xiaohf
     * @Date 8/29/2022 2:19 PM
    **/
    public static void guavaBloomFilter(){
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 1, 0.1);

        System.out.println(bloomFilter.mightContain("a"));
        System.out.println(bloomFilter.mightContain("ab"));

        bloomFilter.put("a");
        bloomFilter.put("c");
        System.out.println(bloomFilter.mightContain("a"));
        System.out.println(bloomFilter.mightContain("c"));
        System.out.println(bloomFilter.mightContain("d"));
        System.out.println(bloomFilter.mightContain("ab"));
        System.out.println(bloomFilter.expectedFpp());

    }

    /**
     * 方法说明：redis的布隆过滤器
     * @param
     * @return void
     * @throws
     * @Author xiaohf
     * @Date 8/29/2022 2:19 PM
    **/
    public static void redisBloomFilter(){
        // TODO: 8/29/2022 未完成

    }


}
